<?php

namespace Unl\HomologacionBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\ExecutionContext;



/**
* @ORM\Entity(repositoryClass="Unl\HomologacionBundle\Repository\PersonaRepository")
* @Assert\Callback(methods={"esIdentificacionValida"})
*/
class Persona
{
    /**
    * @ORM\Id
    * @ORM\Column(type="bigint")
    * @ORM\GeneratedValue(strategy="AUTO")
    */
    protected $id;

    /**
    * @ORM\Column(type="string", length=100)
    * @Assert\NotBlank(message = "Debe ingresar Apellido.")
    */
    protected $apellido;

    /** 
    * @ORM\Column(type="string", length=100)
    * @Assert\NotBlank(message = "Debe ingresar Nombre.")
    */
    protected $nombre;
    
    /** 
    * @ORM\Column(type="string", length=100)
    * @Assert\NotBlank(message = "Debe elegir un tipo de identificaicon.")
    */
    protected $tipoIdentificacion;

    /**
    * @ORM\Column(type="string", length=20 , nullable=true)
    * @Assert\MinLength(limit = 10, message = "El campo cedula debe tener {{ limit }} digitos."	)
    * @Assert\MaxLength(limit = 10, message = "El campo pasaporte debe tener {{ limit }} digitos." )
    */
    protected $cedula;

    /**
    * @ORM\Column(type="string", length=20 , nullable=true)
    * @Assert\MinLength(limit = 5, message = "El campo pasaporte debe tener mínimo {{ limit }} digitos.")
    * @Assert\MaxLength(limit = 10, message = "El campo pasaporte debe tener máximo {{ limit }} digitos." )
    */
    protected $pasaporte;
    
    
    /**
    * @ORM\Column(type="string", length=100, nullable=true)
    */
    protected $telefono;



    /**
    * @ORM\OneToOne(targetEntity="Usuario", cascade={"all"}, inversedBy="persona")
    * @ORM\JoinColumn(name="usuario_id", referencedColumnName="id")
    */
    protected $usuario;
    
    /**
    * @ORM\OneToMany(targetEntity="PeticionHomologacion", mappedBy="persona")
    */
    protected $peticionesHomologacion;


    /**
     * Get id
     *
     * @return bigint 
     */
    
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set apellido
     *
     * @param string $apellido
     */
    public function setApellido($apellido)
    {
        $this->apellido = $apellido;
    }

    /**
     * Get apellido
     *
     * @return string  
     */
    public function getApellido()
    {
        return $this->apellido;
    }

    /**
     * Set nombre
     *
     * @param string $nombre
     */
    public function setNombre($nombre)
    {
        $this->nombre = $nombre;
    }

    /**
     * Get nombre
     *
     * @return string 
     */
    public function getNombre()
    {
        return $this->nombre;
    }

    
    /**
     * Set tipoIdentificacion
     *
     * @param string $tipoIdentificacion
     */
    public function setTipoIdentificacion($tipoIdentificacion)
    {
        $this->tipoIdentificacion = $tipoIdentificacion;
    }

    /**
     * Get nombre
     *
     * @return string 
     */
    public function getTipoIdentificacion()
    {
        return $this->tipoIdentificacion;
    }

    
    
    /**
     * Set cedula
     *
     * @param string $cedula
     */
    public function setCedula($cedula)
    {
        $this->cedula = $cedula;
    }

    /**
     * Get cedula
     *
     * @return string 
     */
    public function getCedula()
    {
        return $this->cedula;
    }

      /**
     * Set pasaporte
     *
     * @param string $pasaporte
     */
    public function setPasaporte($pasaporte)
    {
        $this->pasaporte = $pasaporte;
    }

    /**
     * Get pasaporte
     *
     * @return string 
     */
    public function getPasaporte()
    {
        return $this->pasaporte;
    }
    
    
    /**
     * Set telefono
     *
     * @param string $telefono
     */
    public function setTelefono($telefono)
    {
        $this->telefono = $telefono;
    }

    /**
     * Get telefono
     *
     * @return string 
     */
    public function getTelefono()
    {
        return $this->telefono;
    }

    /**
     * Set usuario
     *
     * @param Unl\HomologacionBundle\Entity\Usuario $usuario
     */
    public function setUsuario($usuario)
    {

        $this->usuario = $usuario;
        
    }

    /**
     * Get usuario
     *
     * @return Unl\HomologacionBundle\Entity\Usuario 
     */
    public function getUsuario()
    {
        return $this->usuario;
    }
    
    public function __toString()
    {
        return $this->nombre.' '.$this->apellido;
    }
    public function __construct()
    {
        $this->usuario = new Usuario();
        $this->usuario->setPersona($this);
   
        
        $this->peticionesHomologacion = new \Doctrine\Common\Collections\ArrayCollection();
    }
    
    /**
     * Add peticionHomologacion
     *
     * @param Unl\HomologacionBundle\Entity\PeticionHomologacion $peticionHomologacion
     */
    public function addPeticionesHomologacion(\Unl\HomologacionBundle\Entity\PeticionHomologacion $peticionHomologacion)
    {
        $this->peticionesHomologacion->add($peticionHomologacion);
        $peticionHomologacion->setPersona($this);
    }

    public function setPeticionesHomologacion($peticionesHomologacion)
    {        
        foreach ($peticionesHomologacion as $peticionHomologacion) {
            $peticionHomologacion->setPersona($this);
        }
        $this->peticionesHomologacion = $peticionesHomologacion;
    }
    
    /**
     * Get peticionHomologacion
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getPeticionesHomologacion()
    {
        return $this->peticionesHomologacion;
    }

    /**
     * Add peticionesHomologacion
     *
     * @param Unl\HomologacionBundle\Entity\PeticionHomologacion $peticionesHomologacion
     */
    public function addPeticionHomologacion(\Unl\HomologacionBundle\Entity\PeticionHomologacion $peticionesHomologacion)
    {
        $this->peticionesHomologacion[] = $peticionesHomologacion;
    }
    
    public function esIdentificacionValida(ExecutionContext $context){
        if($this->tipoIdentificacion === 'cedula'){
            $esValida = $this->esCedulaValida();
            if(!$esValida){
                $context->addViolation('Número de cedula no válido', array(), null);
            }
        } else {
            $esValido = $this->esPasaporteValido();
            if(!$esValido){
                $context->addViolation('Pasaporte no válido', array(), null);
            }
        }
        return true;
    }
    
    protected function esPasaporteValido()
    {
        if (empty($this->pasaporte)) {
            return false;
        }

        if (strlen($this->pasaporte) < 4) {
            return false;
        }

        return true;
    }

    
    
         /**
    * Validar cédula
    *
    * @param string $cedula Número de cédula
    *
    * @return Boolean
*/
    public function esCedulaValida()
    {
        $esValida = true;
        $esValida = $esValida && $this->validarInicial($numero = $this->cedula, '10');
        $esValida = $esValida && $this->validarCodigoProvincia(substr($numero= $this->cedula, 0, 2));
        $esValida = $esValida && $this->validarTercerDigito($numero= $this->cedula[2], 'cedula');
        $esValida = $esValida && $this->algoritmoModulo10(substr($numero= $this->cedula, 0, 9), $numero= $this->cedula[9]);
        
        $esValida = $esValida && $this->algoritmoModulo10(substr($numero=$this->cedula, 0, 9), $numero=$this->cedula[9]);
        return $esValida;
    }
    
    
    
    
        /**
    * Validaciones iniciales para CI
    *
    * @param string $this->cedula CI 
    * @param integer $caracteres Cantidad de caracteres requeridos
    *
    * @return Boolean
    *
    * @throws exception Cuando valor esta vacio, cuando no es dígito y
    * cuando no tiene cantidad requerida de caracteres
    */
    protected function validarInicial($numero,$caracteres)
    {
        if (empty($numero)) {
            //throw $this->createNotFoundException('Valor no puede estar vacio');
            //  throw new Exception('Valor no puede estar vacio');
            return false;
        }
        
        if (!ctype_digit($numero)) {
            //throw $this->createNotFoundException('Valor ingresado solo puede tener dígitos');ç
            return false;
        }

        if (strlen($numero) != $caracteres) {
            //throw $this->createNotFoundException('Valor ingresado debe tener '.$caracteres.' caracteres');
            return false;
        }

        return true;
    }

    /**
    * Validación de código de provincia (dos primeros dígitos de CI)
    *
    * @param string $this->cedula Dos primeros dígitos de CI
    *
    * @return boolean
    *
    * @throws exception Cuando el código de provincia no esta entre 00 y 24
    */
    protected function validarCodigoProvincia($numero)
    {
       
       if ($numero < 0 OR $numero > 24) {
            //throw $this->createNotFoundException('Cédula no válida: El código de provincia no existe');
            //throw new \Exception('Cédula no válida: El código de provincia no existe');
            return false;
      
        }

        return true;
    }
    
    /**
    * Validación de tercer dígito
    *
    * Permite validad el tercer dígito del documento. 
    *
    * Para Cédulas el terder dígito debe
    * estar entre 0 y 5 (0,1,2,3,4,5)
    *
    * @param string $numero tercer dígito de CI
    * @param string $tipo tipo de identificador
    *
    * @return boolean
    *
    * @throws exception Cuando el tercer digito no es válido. El mensaje
    * de error depende del tipo de Idenficiación.
    */
    protected function validarTercerDigito($numero, $tipo)
    {
        switch ($tipo) {
            case 'cedula':
            case 'ruc_natural':
                if ($numero < 0 OR $numero > 5) {
                   return false;
                }
                break;
      
        default:
               return false;
                break;
        }

        return true;
    }

    
    /**
    * Validación de tercer dígito
    *
    * Permite validad el tercer dígito del documento. 
    *
    * Para Cédulas el terder dígito debe
    * estar entre 0 y 5 (0,1,2,3,4,5)
    *
    * @param string $cedula tercer dígito de CI
    * @param string $tipo tipo de identificador
    *
    * @return boolean
    *
    * @throws exception Cuando el tercer digito no es válido. El mensaje
    * de error depende del tipo de Idenficiación.
    *
    protected function validarTercerDigito($tipo)
    {
        switch ($tipo) {
            case 'cedula':
            case 'ruc_natural':
                if ($this->cedula < 0 OR $this->cedula > 5) {
                    throw $this->createNotFoundException('Cédula no válida');
                }
                break;
      
        default:
                throw $this->createNotFoundException('Tipo de Identificacion no existe.');
                break;
        }

        return true;
    }*/

/**
* Algoritmo Modulo10 para validar si CI. Son válidos.
*
* Los coeficientes usados para verificar el décimo dígito de la cédula,
* mediante el algoritmo “Módulo 10” son: 2. 1. 2. 1. 2. 1. 2. 1. 2
*
* Paso 1: Multiplicar cada dígito de los digitosIniciales por su respectivo
* coeficiente.
*
* Ejemplo
* digitosIniciales posicion 1 x 2
* digitosIniciales posicion 2 x 1
* digitosIniciales posicion 3 x 2
* digitosIniciales posicion 4 x 1
* digitosIniciales posicion 5 x 2
* digitosIniciales posicion 6 x 1
* digitosIniciales posicion 7 x 2
* digitosIniciales posicion 8 x 1
* digitosIniciales posicion 9 x 2
*
* Paso 2: Sí alguno de los resultados de cada multiplicación es mayor a o igual a 10,
* se suma entre ambos dígitos de dicho resultado. Ex. 12->1+2->3
*
* Paso 3: Se suman los resultados y se obtiene total
*
* Paso 4: Divido total para 10, se guarda residuo. Se resta 10 menos el residuo.
* El valor obtenido debe concordar con el digitoVerificador
*
* Nota: Cuando el residuo es cero(0) el dígito verificador debe ser 0.
*
* @param string $digitosIniciales Nueve primeros dígitos de CI
* @param string $digitoVerificador Décimo dígito de CI
*
* @return boolean
*
* @throws exception Cuando los digitosIniciales no concuerdan contra
* el código verificador.
*/
    protected function algoritmoModulo10($digitosIniciales, $digitoVerificador)
    {
        $arrayCoeficientes = array(2,1,2,1,2,1,2,1,2);

        $digitoVerificador = (int)$digitoVerificador;
        $digitosIniciales = str_split($digitosIniciales);

        $total = 0;
        foreach ($digitosIniciales as $key => $value) {

            $valorPosicion = ( (int)$value * $arrayCoeficientes[$key] );

            if ($valorPosicion >= 10) {
                $valorPosicion = str_split($valorPosicion);
                $valorPosicion = array_sum($valorPosicion);
                $valorPosicion = (int)$valorPosicion;
            }

            $total = $total + $valorPosicion;
        }

        $residuo = $total % 10;

        if ($residuo == 0) {
            $resultado = 0;
        } else {
            $resultado = 10 - $residuo;
        }

        if ($resultado != $digitoVerificador) {
            //throw $this->createNotFoundException('Cédula no válida');
            return false;
        }

        return true;
    }

    
}
